home *** CD-ROM | disk | FTP | other *** search
/ Programming a Multiplayer FPS in DirectX / Programming a Multiplayer FPS in DirectX (Companion CD).iso / DirectX / dxsdk_oct2004.exe / dxsdk.exe / Documentation / DirectX9 / directplay.chm / code / objectmembers2.js < prev    next >
Encoding:
Text File  |  2004-09-27  |  19.7 KB  |  640 lines

  1. //Load the config file.
  2. //The config contains the path to be walked or the path to an individual file.
  3. //The path to the data file to be updated.
  4.  
  5. WScript.Echo(new Date());                // echo when the code started.
  6.  
  7. var start = new Date();    //Used for perf testing
  8. var sDate=start.getHours() + ":" + start.getMinutes() + ":" + start.getSeconds() + ":" + start.getMilliseconds()
  9.  
  10. var warningCount = 0;
  11. var errorCount = 0;
  12.  
  13. var gScriptPath=WScript.ScriptFullName.substr(0,2);
  14. //gfs = new ActiveXObject("Scripting.FileSystemObject");
  15. var oArgs = WScript.Arguments;
  16. var gsConfigPath = oArgs(0);            //Config file
  17. var goIterator=new IteratorClass(gsConfigPath);
  18. goIterator.walk(goIterator.rootPath);
  19. //WScript.Echo(goIterator.fileCount);
  20. goIterator.done();
  21.  
  22. WScript.Echo("The number of errors are " + errorCount + ".");
  23. WScript.Echo("The number of warnings are " + warningCount + ".");
  24. WScript.Echo(new Date());                // echo when the code finished.
  25.  
  26. //Constructor for iterator object
  27. function IteratorClass(sConfigPath)
  28. {
  29.     this.fileCount=0;
  30.     this.fs = new ActiveXObject("Scripting.FileSystemObject");
  31.     this.datasets = new Array();
  32.     this.destinations= new Array();
  33.     this.configFile=getConfig(sConfigPath);
  34.     this.getDestination=getDestination;
  35.     this.destinationNodes=this.configFile.selectNodes("/root/datafile")
  36.     for (var i=0;i<this.destinationNodes.length;i++)
  37.     {
  38.         this.destinations[i]=new DestinationClass(this.destinationNodes.item(i))
  39.     }
  40.     this.providerNodes=this.configFile.selectNodes("/root/provider");
  41.     for (var i=0;i<this.providerNodes.length;i++)
  42.     {
  43.         var datasetName=this.providerNodes.item(i).getAttribute("datafilerid");
  44.         this.datasets[i]=new DataSetClass(this.configFile,this.providerNodes.item(i),this.getDestination(datasetName));
  45.         //WScript.Echo(this.datasets[i].name);
  46.     }
  47.     this.rootPath=this.configFile.selectSingleNode("/root/sourcefiles").text;
  48.     this.rootPath=EnsureDriveLetter(this.rootPath);
  49.     this.done=SaveAll;
  50.     this.passAround=passAround;
  51.     this.walk=recursWalk;
  52.     return this;
  53. }
  54.  
  55.  
  56. //Constructor for dataset object
  57. function DataSetClass(oConfigFile,providerNode,destination)
  58. {
  59.     //var start = new Date();    //Used for perf testing
  60.     //this.startTime=start.getHours() + ":" + start.getMinutes() + ":" + start.getSeconds() + ":" + start.getMilliseconds()
  61.     //this.endTime="";
  62.     this.queryID="";
  63.     this.fixedID="";
  64.     this.datasetName=providerNode.getAttribute("datafilerid");
  65.     this.name=providerNode.getAttribute("name");
  66.     this.configFile=oConfigFile;
  67.     //bugbug: These calls should use nodefromid
  68.     //var templatePath=this.configFile.selectSingleNode("/root/datafile[@id='" + this.datasetName + "']").getAttribute("template_path");
  69.     //this.outputPath=this.configFile.selectSingleNode("/root/datafile[@id='" + this.datasetName + "']").getAttribute("output_path");
  70.     //bugbug what if you cannot open the template- log the failure and end
  71.     this.template=destination    //getConfig(templatePath);
  72.     
  73.     this.qualifyingQueries= new Array();
  74.     var qualifyNodes=providerNode.selectNodes("./qualify");
  75.     for (var i=0;i<qualifyNodes.length;i++){
  76.         this.qualifyingQueries[i]=qualifyNodes.item(i).getAttribute("value");
  77.         //WScript.Echo(this.qualifyingQueries[i]);
  78.     }
  79.     
  80.     this.groups= new Array();
  81.     var groupNodes=providerNode.selectNodes("./group_by")    
  82.     for (var i=0;i<groupNodes.length;i++)
  83.     {
  84.         var g = groupNodes.item(i);
  85.         var nameCaption=g.getAttribute("namecaption")
  86.         var pnCaption=g.getAttribute("pncaption")
  87.         var gid = g.getAttribute("id");
  88.         var devlang = g.getAttribute("devlang");
  89.         
  90.         // peterril:  added capability to force unique entries
  91.         //              duplicates are possible in situations like a page is for both VB and Script
  92.         //              where they are both objects and they may match multiple criteria.
  93.         //
  94.         //              @unique can exist on a group or provider.
  95.         var unique = (g.getAttribute("unique") ||         
  96.                       g.selectSingleNode("..").getAttribute("unique") 
  97.                       ? true : false);
  98.         
  99.         if (!nameCaption) nameCaption="";    
  100.         if (!pnCaption) pnCaption="";
  101.         if (!devlang) devlang="";
  102.             
  103.         this.groups[i]=new GroupClass(groupNodes.item(i).getAttribute("id"), 
  104.                                       groupNodes.item(i).getAttribute("name"),
  105.                                       groupNodes.item(i).getAttribute("value"), 
  106.                                       nameCaption, pnCaption, devlang);
  107.         this.groups[i].unique = unique;
  108.     }
  109.  
  110.     this.customPolls = new Array();
  111.     var customPollNodes = providerNode.selectNodes("./dyndesc");
  112.     for( var i=0; i<customPollNodes.length; i++ ){
  113.         this.customPolls[i] = new Object();
  114.         //this.customPolls[i].name = customPollNodes.item(i).getAttribute("name");
  115.         this.customPolls[i].value = customPollNodes.item(i).getAttribute("value");
  116.     }
  117.     
  118.     this.queryID=ensureAttribute(providerNode,"query_id");
  119.     this.fixedID=ensureAttribute(providerNode,"fixed_id");
  120.     //WScript.Echo(this.queryID);
  121.     //WScript.Echo(this.fixedID);
  122.     this.process=process;
  123.     this.qualifies=qualifies;
  124.     //this.save=save;
  125.     this.updateDataFromDoc=updateDataFromDoc;
  126.     this.getGroupName=getGroupName;
  127.     this.getGroup=getGroup;
  128.     this.ensureObject=ensureObject;
  129.     return this;
  130. }
  131.  
  132. function getDestination(destinationName)
  133. {
  134.     for (var i=0;i<this.destinations.length;i++)
  135.     {
  136.         if (this.destinations[i].name==destinationName)
  137.         {
  138.             return this.destinations[i].template
  139.         }
  140.     }
  141.     //bugbug: What about failure?
  142. }
  143.  
  144. //Constructor for the destination class
  145. function DestinationClass(destinationNode)
  146. {
  147.     var start = new Date();    //Used for perf testing
  148.     this.startTime=start.getHours() + ":" + start.getMinutes() + ":" + start.getSeconds() + ":" + start.getMilliseconds()
  149.     this.name=destinationNode.getAttribute("id");
  150.     this.outputPath=destinationNode.getAttribute("output_path");
  151.     this.template=getConfig(EnsureDriveLetter(destinationNode.getAttribute("template_path")));
  152.     this.outputPath=EnsureDriveLetter(this.outputPath);
  153.     return this
  154. }
  155.  
  156. function EnsureDriveLetter(sPath)
  157. {
  158.     if (sPath.substr(1,1)!=":")
  159.     {
  160.         return gScriptPath + sPath;
  161.     }
  162.     else
  163.     {
  164.         return sPath;
  165.     }
  166. }
  167.  
  168. function SaveAll()
  169. {
  170.     var fso = new ActiveXObject("Scripting.FileSystemObject");
  171.  
  172.     var end = new Date();
  173.     var sDate= end.getHours() + ":" + end.getMinutes() + ":" + end.getSeconds() + ":" + end.getMilliseconds()
  174.     for (var i=0;i<this.destinationNodes.length;i++)
  175.     {
  176.         this.destinations[i].template.documentElement.setAttribute("StartTime",this.destinations[i].startTime);
  177.         this.destinations[i].template.documentElement.setAttribute("EndTime",sDate);
  178.  
  179.         // make sure the file is not read-only.
  180.         if (fso.FileExists(this.destinations[i].outputPath))
  181.             fso.GetFile(this.destinations[i].outputPath).Attributes = 0;
  182.  
  183.         this.destinations[i].template.save(this.destinations[i].outputPath);
  184.     }
  185. }
  186.  
  187. function passAround(sPath)
  188. {
  189.     WScript.Echo(sPath);
  190.     
  191.     var xmlDoc=getConfig(sPath);
  192.     if( xmlDoc.parseError != 0 ){
  193.         WScript.Echo( ".... ERROR: Unable to validate ('" + xmlDoc.parseError.reason + "')" );
  194.         errorCount++;
  195.         return;
  196.     }
  197.     
  198.     for (var i=0;i<this.providerNodes.length;i++)
  199.     {
  200.         this.datasets[i].process(xmlDoc);
  201.     }    
  202. }
  203.  
  204. function recursWalk(sPath){        //recursively walk the tree and process each xml file
  205.     var colFiles=this.fs.GetFolder(sPath).files
  206.     var enumFiles=new Enumerator(colFiles)
  207.     for (;!enumFiles.atEnd(); enumFiles.moveNext())
  208.     {
  209.         var oFile=enumFiles.item();
  210.         if (oFile.path.toLowerCase().indexOf(".xml") != -1)
  211.         {
  212.             //update(oFile.path);
  213.             this.passAround(oFile.path);
  214.             this.fileCount++;
  215.         }
  216.     }
  217.     var colFolders=this.fs.GetFolder(sPath).SubFolders
  218.     if (colFolders)
  219.     {
  220.         var enumFolders=new Enumerator(colFolders)
  221.         for (;!enumFolders.atEnd(); enumFolders.moveNext())
  222.         {
  223.             var oFolder=enumFolders.item();
  224.             this.walk(oFolder.path);
  225.         }
  226.     }
  227. }
  228.  
  229. //process is a member of the DataSetClass
  230. function process(xmlDoc)
  231. {
  232.     //Does the document qualify?
  233.     if (this.qualifies(xmlDoc))
  234.     {
  235.         //get the data and insert it into the output file
  236.         this.updateDataFromDoc(xmlDoc)
  237.     }
  238. }
  239.  
  240. function qualifies(xmlDoc)
  241. {
  242.     sResult=true;
  243.     for (var i=0;i<this.qualifyingQueries.length;i++)
  244.     {
  245.         if(this.qualifyingQueries[i]){
  246.             try{
  247.                 var testNode=xmlDoc.selectSingleNode(this.qualifyingQueries[i]);
  248.                 if (!testNode)
  249.                 {
  250.                     //WScript.Echo(xmlDoc.url + " fails " + this.qualifyingQueries[i] + " of " + this.name);
  251.                     sResult=false;
  252.                     return sResult;
  253.                 }
  254.             } catch(e) {
  255.                 WScript.Echo( ".... ERROR: Unable to qualify provider '" + this.name + "' ('" + e.message + "')" );
  256.                 errorCount++;
  257.                 this.qualifyingQueries[i] = null;
  258.                 sResult = false;
  259.             }
  260.         }
  261.     }
  262.     return sResult;
  263. }
  264.  
  265.  
  266. function save()
  267. {
  268.     var end = new Date();
  269.     var sDate= end.getHours() + ":" + end.getMinutes() + ":" + end.getSeconds() + ":" + end.getMilliseconds()
  270.     this.template.documentElement.setAttribute("StartTime",this.startTime);
  271.     this.template.documentElement.setAttribute("EndTime",sDate);
  272.  
  273.     // make sure the file is not read-only.
  274.     if (fso.FileExists(this.outputPath))
  275.         fso.GetFile(this.outputPath).Attributes = 0;
  276.  
  277.     this.template.save(this.outputPath);    
  278. }
  279.  
  280. function ensureAttribute(oNode,sAttribute)
  281. {
  282.     var sResult=oNode.getAttribute(sAttribute);
  283.     if (sResult)
  284.     {
  285.         return sResult;
  286.     }
  287.     else
  288.     {
  289.         return "";
  290.     }
  291. }
  292.  
  293. function GroupClass(sID, sName, sQuery, sNameCaption, sPNCaption, devlang)
  294. {
  295.     this.id=sID;
  296.     this.name=sName;
  297.     this.query=sQuery;
  298.     this.nameCaption=sNameCaption;
  299.     this.pnCaption=sPNCaption;
  300.     this.devlang=devlang;
  301.     return this;
  302. }
  303.  
  304. //returns the XMLdocument that is the configuration file
  305. function getConfig(sConfigPath)
  306. {
  307.     var oConfigFile = new ActiveXObject("Microsoft.XMLDOM");
  308.     oConfigFile.resolveExternals=true;
  309.     oConfigFile.validateOnParse=true;
  310.     oConfigFile.async=false;
  311.     oConfigFile.load(sConfigPath);
  312.     var parseErr=oConfigFile.parseError;
  313.     if (parseErr.errorCode != 0)
  314.     {
  315.         var reason=parseErr.reason
  316.         var line=parseErr.line
  317.         var srcText=parseErr.srcText
  318.         //WScript.Echo(reason + " " + line + " " + srcText);
  319.     }
  320.     return oConfigFile;
  321. }
  322.  
  323. function updateDataFromDoc(sourceDoc)
  324. {
  325.     //Gather up the key pieces of this member to be inserted into all it's parent objects and interfaces
  326.     var sRid=sourceDoc.selectSingleNode("/inetsdk:topic/metadata/@id").value;
  327.     
  328.     if(sRid != this.fixedID && sRid != this.queryID){
  329.         var oPN=sourceDoc.selectSingleNode("/inetsdk:topic/metadata/@pn");
  330.         var oOverloaded=sourceDoc.selectSingleNode("/inetsdk:topic/metadata/@overloaded");
  331.         var oProdRid = sourceDoc.selectSingleNode("/inetsdk:topic/content/info/product/@rid");
  332.         var oMinver = sourceDoc.selectSingleNode("/inetsdk:topic/content/info/product/@minver");
  333.         var sSortKey = sourceDoc.selectSingleNode("/inetsdk:topic/metadata/@name").value;
  334.  
  335.         if(oPN)
  336.             var sPN=oPN.value;
  337.  
  338.         if (oOverloaded)
  339.             var oParams = sourceDoc.selectNodes("/inetsdk:topic/content/params");
  340.  
  341.         if (oProdRid)
  342.             var sProdRid = oProdRid.value;
  343.  
  344.         if (oMinver)
  345.             var sMinver = oMinver.value;
  346.  
  347.         //bugbug: member element needs to be a child of member type element
  348.         var sType=sourceDoc.selectSingleNode("/inetsdk:topic/metadata/@type").value
  349.  
  350.         // peterril:  special case happens when a page is only an attribute.    
  351.         var sName = "";
  352.         if( sType != "attribute" )
  353.             sName=sourceDoc.selectSingleNode("/inetsdk:topic/metadata/@name").value
  354.  
  355.         // Use alternative name where available (currently only for script command ids)
  356.         var sAltName = "";
  357.         var oName = sourceDoc.selectSingleNode("/inetsdk:topic/metadata/devlang[@value='scr']/@name");
  358.         if ( oName )
  359.           sAltName = oName.value;
  360.  
  361.         var oDesc = pollCustom( this.customPolls, sourceDoc);
  362.         if( !oDesc )
  363.             oDesc=sourceDoc.selectSingleNode("/inetsdk:topic/content/desc");            // try to get main description.
  364.         if( !oDesc ){
  365.             oDesc=sourceDoc.selectSingleNode("/inetsdk:topic//abstract");            // common in overviews.
  366.     
  367.             // -peterril-
  368.             // the only way I know to rename a node is to create a new one and transfer the information.
  369.             // 
  370.             // the reason that I rename the node is because I wanted to maintain consistancy with the
  371.             // objectmembers code.  This way, the objectmembers code can always assume a desc.
  372.             //
  373.             if( oDesc ){
  374.                 var t = oDesc;
  375.                 oDesc = sourceDoc.createElement("desc");
  376.                 var t = t.firstChild;
  377.                 while(t){
  378.                     oDesc.appendChild( t.cloneNode(true) );
  379.                     t = t.nextSibling;
  380.                 }
  381.             }
  382.         }
  383.         if( !oDesc )
  384.             oDesc = sourceDoc.createElement("desc");        // create blank description.
  385.  
  386.  
  387.         var bNotSupported = (sourceDoc.selectSingleNode("/inetsdk:topic/metadata/@not_supp") ? true : false);
  388.         var bNotImplemented = (sourceDoc.selectSingleNode("/inetsdk:topic/metadata/@not_impl") ? true : false);
  389.     
  390.         if( bNotSupported )
  391.             oDesc.text = "Not currently supported.";
  392.         else if( bNotImplemented )
  393.             oDesc.text = "Not currently implemented.";
  394.  
  395.         var oDescClone;
  396.  
  397.         if (this.fixedID!="")
  398.         {
  399.             var group=this.getGroup(sourceDoc);
  400.             if (!group) return;
  401.  
  402.             var objectNode=this.ensureObject(this.fixedID,group);
  403.             if ( group.devlang != "" )
  404.               objectNode.setAttribute( "devlang", group.devlang );
  405.  
  406.             var member=this.template.createElement("member")
  407.             member.setAttribute("rid",sRid);
  408.             if(sName) member.setAttribute("name",sName);
  409.             if ( sAltName != "" ) member.setAttribute( "altname", sAltName );
  410.             member.setAttribute("sortkey", sSortKey);
  411.             if (oPN) member.setAttribute("pn", sPN);
  412.             if (oProdRid) member.setAttribute("prodrid", sProdRid);
  413.             if (oMinver) member.setAttribute("minver", sMinver);
  414.  
  415.             var oDispID = sourceDoc.selectSingleNode("/inetsdk:topic/metadata/applies/iface[@rid = '" + parentID + "']/@dispid");
  416.             if( oDispID ) var sDispID = oDispID.value;
  417.                 
  418.             if(oDispID) member.setAttribute("dispid", sDispID);
  419.  
  420.             member.setAttribute("type",sType);
  421.             objectNode.appendChild(member);
  422.  
  423.             if (oDesc){
  424.                 if( oDesc[0] ){
  425.                     for( var j=0; j<oDesc.length; j++ ){
  426.                         oDescClone = oDesc[j].cloneNode(true);
  427.                         member.appendChild(oDescClone);
  428.                     }
  429.                 } else {
  430.                     oDescClone=oDesc.cloneNode(true);
  431.                     member.appendChild(oDescClone);        //Add this member to the object
  432.                     
  433.                     if( !oDesc.firstChild ){        // echo warning that there is no description.
  434.                         WScript.Echo(".... WARNING: A default description was created because none existed in document.");
  435.                         warningCount++;
  436.                     }
  437.                 }
  438.             } else {
  439.                 WScript.Echo( ".... ERROR: Unable to retrieve required description." );
  440.                 errorCount++;
  441.             }
  442.  
  443.             if (oOverloaded)
  444.             {
  445.                 for (i = 0; i < oParams.length; i++)
  446.                     member.appendChild(oParams[i].cloneNode(true));
  447.             }
  448.         }
  449.         else        //BUGBUG: Missing dispid from the ifaces and autoiid on the members.
  450.         {
  451.             var group=this.getGroup(sourceDoc);
  452.             if (!group) return;
  453.                 
  454.             var parentNodes=sourceDoc.selectNodes(this.queryID);
  455.             for (var i=0;i<parentNodes.length;i++)
  456.             {
  457.                 var parentID=parentNodes[i].text
  458.                 var oAIs = parentNodes[i].selectNodes("../accessinfo");    // hack to go back up to parent tag.
  459.                 var oAIClone = null;
  460.                 var objectNode=this.ensureObject(parentID, group, group.devlang);
  461.                 
  462.                 //peterril: check to verify that there are no duplicates if set in config.
  463.                 var isUnique = true;
  464.                 if( group.unique ) isUnique = isUniqueRecord( sRid, objectNode );
  465.                 
  466.                 if( !isUnique )
  467.                 {
  468.                     WScript.Echo(".... ERROR: Discarded record because uniquness was enforced [" + parentID + "].");
  469.                     errorCount++;
  470.                 }
  471.                 else
  472.                 {
  473.                     if ( group.devlang != "" )
  474.                         objectNode.setAttribute( "devlang", group.devlang );
  475.  
  476.                     var member = this.template.createElement("member");
  477.                     member.setAttribute("rid",sRid);
  478.                     if(sName) member.setAttribute("name",sName);
  479.                     if ( sAltName != "" ) member.setAttribute( "altname", sAltName );
  480.                     member.setAttribute("sortkey", sSortKey);
  481.                     if(oPN) member.setAttribute("pn",sPN);
  482.                     if(oMinver) member.setAttribute("minver",sMinver);
  483.  
  484.                     var oDispID = sourceDoc.selectSingleNode("/inetsdk:topic/metadata/applies/iface[@rid = '" + parentID + "']/@dispid");
  485.                     if( oDispID ) var sDispID = oDispID.value;
  486.                 
  487.                     if(oDispID) member.setAttribute("dispid", sDispID);
  488.                     member.setAttribute("type",sType);
  489.                     objectNode.appendChild(member);
  490.  
  491.                     // insert description information.
  492.                     if (oDesc){
  493.                         if( oDesc[0] ){
  494.                             for( var j=0; j<oDesc.length; j++ ){
  495.                                 oDescClone = oDesc[j].cloneNode(true);
  496.                                 member.appendChild(oDescClone);
  497.                             }
  498.                         } else {
  499.                             oDescClone=oDesc.cloneNode(true);
  500.                             member.appendChild(oDescClone);        //Add this member to the object
  501.                             
  502.                             if( !oDesc.firstChild ){        // echo warning that there is no description.
  503.                                 WScript.Echo(".... WARNING: A default description was created because none existed in document.");
  504.                                 warningCount++;
  505.                             }
  506.                         }
  507.                     } else {
  508.                         WScript.Echo( ".... ERROR: Unable to retrieve required description." );
  509.                         errorCount++;
  510.                     }
  511.  
  512.                     // insert accessinfo information.
  513.                     for( var j=0; j<oAIs.length; j++ ){
  514.                         var oAI = oAIs[j];
  515.                         oAIClone = oAI.cloneNode( true );
  516.                         member.appendChild( oAIClone );
  517.                     }
  518.                     
  519.                     if (oOverloaded)
  520.                     {
  521.                         for (i = 0; i < oParams.length; i++)
  522.                             member.appendChild(oParams[i].cloneNode(true));
  523.                     }
  524.                 }
  525.             }
  526.         }
  527.     }
  528. }
  529.  
  530. function isUniqueRecord(idToFind, sourceData){
  531.     var result = true;
  532.     
  533.     if(idToFind && sourceData){
  534.         var t = sourceData.selectSingleNode("member[@rid='" + idToFind + "']");
  535.         if(t) result = false;
  536.     }
  537.     
  538.     return result;
  539. }
  540.  
  541. function pollCustom( aPollsFound, sourceDoc ){
  542.     for( var i=0; i<aPollsFound.length; i++ ){
  543.         var searchValue = aPollsFound[i].value;
  544.         
  545.         var foundNodes = sourceDoc.selectNodes( searchValue );
  546.         
  547.         if( foundNodes.length >= 1 )
  548.             return renameNode(foundNodes[i], "desc");
  549.         else 
  550.             return null;
  551.     }
  552. }
  553.  
  554. function renameNode( srcNode, newName ){
  555.     var xml = new ActiveXObject("Microsoft.XMLDOM");
  556.     
  557.     if( srcNode && newName ){
  558.         if( srcNode.nodeName == newName )
  559.             return srcNode.cloneNode(true);
  560.         
  561.         var t = xml.createElement(newName);
  562.         var c = srcNode.firstChild;
  563.         while(c){
  564.             t.appendChild(c.cloneNode(true));
  565.             c = c.nextSibling;
  566.         }
  567.         
  568.         for( var i=0; i<srcNode.attributes.length; i++ ){
  569.             var att = srcNode.attributes[i];
  570.             t.setAttribute( att.nodeName, att.nodeValue );
  571.         }
  572.         
  573.         return t;
  574.     } else 
  575.         return null;
  576. }
  577.  
  578. function ensureObject(sParentID, oType, devlang){
  579.     //var objectNode=this.template.selectSingleNode("/objectmembers/parent[@id='" + sParentID + "']")
  580.     var objectNode=this.template.nodeFromID(sParentID)
  581.     if (!objectNode)
  582.     {
  583.         objectNode=this.template.createElement("parent")
  584.         this.template.documentElement.appendChild(objectNode)
  585.         objectNode.setAttribute("id",sParentID);
  586.     }
  587.     
  588.     var typeNode = "";
  589.     if(devlang)
  590.         typeNode=this.template.selectSingleNode("/objectmembers/parent[@id='" + sParentID + "']/type[@gid='" + oType.id + "' $and$ @devlang='" + devlang + "']")
  591.     else
  592.         typeNode=this.template.selectSingleNode("/objectmembers/parent[@id='" + sParentID + "']/type[@gid='" + oType.id + "']")
  593.     if (!typeNode)
  594.     {
  595.         typeNode=this.template.createElement("type")
  596.         objectNode.appendChild(typeNode)
  597.         typeNode.setAttribute("value",oType.name);
  598.         typeNode.setAttribute("namecaption",oType.nameCaption);
  599.         typeNode.setAttribute("gid", oType.id);
  600.         typeNode.setAttribute("pncaption",oType.pnCaption);
  601.         if(devlang) typeNode.setAttribute("devlang", devlang);
  602.     }
  603.     return typeNode;
  604. }
  605.  
  606. function getGroupName(xmlDoc)
  607. {
  608.     var sResult="unknown";
  609.     for (var i=0;i<this.groups.length;i++)
  610.     {
  611.         if (xmlDoc.selectSingleNode(this.groups[i].query))
  612.         {
  613.             sResult=this.groups[i].name;
  614.             break;
  615.         }
  616.     }
  617.     return sResult;
  618. }
  619.  
  620. function getGroup(xmlDoc)
  621. {
  622.     for (var i=0;i<this.groups.length;i++)
  623.     {
  624.         if(this.groups[i].query){
  625.             try{
  626.                 if (xmlDoc.selectSingleNode(this.groups[i].query))
  627.                 {
  628.                     return this.groups[i];
  629.                 }
  630.             } catch(e) {
  631.                 WScript.Echo( ".... ERROR: Unable to qualify provider '" + this.name + "' ('" + e.message + "')" );
  632.                 errorCount++;
  633.                 this.groups[i].query = null;
  634.                 return null;
  635.             }
  636.         }
  637.     }
  638. }
  639.  
  640.